#include "Init.h"

// 选择专业
std::string major_choice()
{
    curs_set(0); // 隐藏光标
    std::vector<std::string> major_list;
    major_list.push_back("Data Science and Big Data Technology");
    major_list.push_back("Network Engineering");
    major_list.push_back("Intelligent Science and Technology");
    major_list.push_back("Cyberspace Security");

    // 创建窗口
    WINDOW *major_win = newwin(10, 42, (LINES - 10) / 2, (COLS - 40) / 2);
    WINDOW *major_win2 = derwin(major_win, 6, 38, 3, 1);
    // 创建子窗口
    box(major_win, 0, 0);
    mvwprintw(major_win, 0, 1, "Choose your major");
    // 创建菜单项
    std::vector<ITEM *> items;
    for (auto it = major_list.begin(); it != major_list.end(); ++it)
    {
        items.push_back(new_item(it->c_str(), ""));
    }
    items.push_back(nullptr);
    MENU *major_menu = new_menu(items.data());
    set_menu_win(major_menu, major_win);
    set_menu_sub(major_menu, major_win2);
    set_menu_format(major_menu, 6, 1);
    set_menu_mark(major_menu, " * ");
    set_menu_spacing(major_menu, 1, 1, 1);
    set_menu_grey(major_menu, 1);
    // 创建并设置菜单

    post_menu(major_menu);
    wrefresh(major_win);
    int c;
    while ((c = getch()) != 10)
    {
        switch (c)
        {
        case KEY_UP:
            menu_driver(major_menu, REQ_UP_ITEM);
            break;
        case KEY_DOWN:
            menu_driver(major_menu, REQ_DOWN_ITEM);
            break;
        default:
            break;
        }
        wrefresh(major_win);
    }
    int choice = item_index(current_item(major_menu));
    unpost_menu(major_menu);
    free_menu(major_menu); // 删除菜单
    for (auto it = items.begin(); it != items.end(); ++it)
    {
        free_item(*it);
    } // 删除菜单项
    delwin(major_win);
    delwin(major_win2); // 删除窗口
    // 释放内存
    return major_list[choice];
}

// 填写学生信息
void student_info(nlohmann::json &student)
{
    // 辅助函数：去除字符串首尾空格
    auto trim = [](const std::string &str)
    {
        size_t first = str.find_first_not_of(' ');
        if (std::string::npos == first)
            return std::string();
        size_t last = str.find_last_not_of(' ');
        return str.substr(first, (last - first + 1));
    };

    // 辅助函数：显示表单错误
    auto show_form_error = [](WINDOW *win, const std::string &message)
    {
        mvwprintw(win, 20, 5, "%s", message.c_str()); // 显示错误消息
        wrefresh(win);
        napms(2000);                        // 显示2秒
        mvwprintw(win, 20, 5, "%-50s", ""); // 清除错误消息
    };

    // 常量定义
    const int FORM_WIDTH = 80;     // 表单总宽度
    const int FORM_HEIGHT = 24;    // 表单总高度
    const int FIELD_LENGTH = 50;   // 字段可输入长度
    const int FIELD_Y_OFFSET = 2;  // 字段Y起始位置
    const int FIELD_X_OFFSET = 20; // 字段X起始位置
    const int LABEL_X_OFFSET = 5;  // 标签X偏移量
    const int NEXT_BTN_X = 60;     // Next按钮X位置
    const int NEXT_BTN_Y = 18;     // Next按钮Y位置

    // 显示普通光标
    curs_set(1);

    // 创建表单字段
    std::vector<FIELD *> fields = {
        new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 0, FIELD_X_OFFSET, 0, 0), // 名字
        new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 2, FIELD_X_OFFSET, 0, 0), // 学号
        new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 4, FIELD_X_OFFSET, 0, 0), // 班级
        new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 6, FIELD_X_OFFSET, 0, 0), // Git仓库
        // new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 8, FIELD_X_OFFSET, 0, 0),  // 仓库
        new_field(1, FIELD_LENGTH, FIELD_Y_OFFSET + 8, FIELD_X_OFFSET, 0, 0), // 邮箱
        nullptr                                                               // 结束标记
    };

    // 设置字段属性
    for (auto field : fields)
    {
        if (!field)
            continue;

        set_field_back(field, A_UNDERLINE);
        field_opts_off(field, O_AUTOSKIP);

        // 设置字段验证
        set_field_type(field, TYPE_REGEXP, "^.+$"); // 非空验证
        set_max_field(field, FIELD_LENGTH);         // 设置最大长度
    }

    // 创建表单窗口
    WINDOW *form_win = newwin(FORM_HEIGHT, FORM_WIDTH,
                              (LINES - FORM_HEIGHT) / 2,
                              (COLS - FORM_WIDTH) / 2);
    WINDOW *form_subWin = derwin(form_win, FORM_HEIGHT - 4, FORM_WIDTH - 10, 2, 5);
    box(form_win, 0, 0);
    mvwprintw(form_win, 0, 1, "Please fill in your information");
    keypad(form_win, TRUE);

    // 创建并设置表单
    FORM *form = new_form(fields.data());
    set_form_win(form, form_win);
    set_form_sub(form, form_subWin);
    post_form(form);
    set_current_field(form, fields[0]); // 设置第一个字段为当前字段

    // 显示标签
    const std::vector<std::string> labels = {
        "Name:", "Student ID:", "Class:", "Git URL:", "Email:"};
    for (size_t i = 0; i < labels.size(); ++i)
    {
        mvwprintw(form_win, FIELD_Y_OFFSET + i * 2 + 2, LABEL_X_OFFSET, "%s", labels[i].c_str());
    }
    mvwprintw(form_win, NEXT_BTN_Y, LABEL_X_OFFSET, "Tab to switch, Enter to submit");

    // 绘制Next按钮
    mvwprintw(form_win, NEXT_BTN_Y, NEXT_BTN_X, "[ Next ]");
    wrefresh(form_win);

    // 当前焦点状态 (0:表单, 1:按钮)
    int focus_state = 0;
    bool running = true;

    // 初始化表单驱动
    form_driver(form, REQ_FIRST_FIELD);
    form_driver(form, REQ_END_LINE);

    // 表单处理循环
    while (running)
    {
        int ch = wgetch(form_win);

        if (focus_state == 0)
        {
            // 表单焦点处理
            curs_set(1);

            switch (ch)
            {
            case KEY_DOWN:
                form_driver(form, REQ_NEXT_FIELD);
                form_driver(form, REQ_END_LINE);
                break;
            case KEY_UP:
                form_driver(form, REQ_PREV_FIELD);
                form_driver(form, REQ_END_LINE);
                break;
            case KEY_LEFT:
                form_driver(form, REQ_PREV_CHAR);
                break;
            case KEY_RIGHT:
                form_driver(form, REQ_NEXT_CHAR);
                break;
            case KEY_BACKSPACE:
            case 127:
                form_driver(form, REQ_DEL_PREV);
                break;
            case '\t':
                // 切换到按钮
                focus_state = 1;
                curs_set(0);
                wattron(form_win, A_REVERSE);
                mvwprintw(form_win, NEXT_BTN_Y, NEXT_BTN_X, "[ Next ]");
                wattroff(form_win, A_REVERSE);
                wrefresh(form_win);
                break;
            case '\n':
                form_driver(form, REQ_NEXT_FIELD);
                form_driver(form, REQ_END_LINE);
                break;
            default:
                form_driver(form, ch);
                break;
            }
        }
        else
        {
            // 按钮焦点处理
            curs_set(0);

            switch (ch)
            {
            case '\t':
                // 切换回表单
                focus_state = 0;
                wattrset(form_win, A_NORMAL);
                mvwprintw(form_win, NEXT_BTN_Y, NEXT_BTN_X, "[ Next ]");
                wrefresh(form_win);
                form_driver(form, REQ_FIRST_FIELD);
                form_driver(form, REQ_END_LINE);
                break;
            case '\n':
                // 验证并提交表单
                form_driver(form, REQ_VALIDATION);

                // 检查所有字段是否已填写
                bool all_filled = true;
                for (auto field : fields)
                {
                    if (!field)
                        continue;

                    char *buf = field_buffer(field, 0);
                    if (!buf || strlen(trim(buf).c_str()) == 0)
                    {
                        all_filled = false;
                        break;
                    }
                }

                if (all_filled)
                {
                    running = false;
                }
                else
                {
                    show_form_error(form_win, "Please fill all fields!");
                    focus_state = 0;
                    wattrset(form_win, A_NORMAL);
                    mvwprintw(form_win, NEXT_BTN_Y, NEXT_BTN_X, "[ Next ]");
                    set_current_field(form, fields[0]);
                    wrefresh(form_win);
                    form_driver(form, REQ_FIRST_FIELD);
                    form_driver(form, REQ_END_LINE);
                }
                break;
            }
        }
    }

    // 获取并处理字段值
    auto get_field_value = [&fields, &trim](int index)
    {
        std::string value = trim(field_buffer(fields[index], 0));
        return value.empty() ? "" : value;
    };

    student["name"] = get_field_value(0);
    student["number"] = get_field_value(1);
    student["class"] = get_field_value(2);
    student["git"] = get_field_value(3);
    student["email"] = get_field_value(4);

    // 清理资源
    unpost_form(form);
    free_form(form);

    for (auto field : fields)
    {
        if (field)
            free_field(field);
    }

    delwin(form_subWin);
    delwin(form_win);
    clear();
    refresh();
}

// 编辑器选择
std::string editor_choice()
{
    curs_set(0); // 隐藏光标
    std::vector<std::string> editor_list;
    editor_list.push_back("vim");
    editor_list.push_back("nano");

    // 创建窗口
    WINDOW *editor_win = newwin(10, 42, (LINES - 10) / 2, (COLS - 40) / 2);
    WINDOW *editor_win2 = derwin(editor_win, 6, 38, 3, 1);
    // 创建子窗口
    box(editor_win, 0, 0);
    mvwprintw(editor_win, 0, 1, "Choose your editor");
    // 创建菜单项
    std::vector<ITEM *> items;
    for (auto it = editor_list.begin(); it != editor_list.end(); ++it)
    {
        items.push_back(new_item(it->c_str(), ""));
    }
    items.push_back(nullptr);
    MENU *editor_menu = new_menu(items.data());
    set_menu_win(editor_menu, editor_win);
    set_menu_sub(editor_menu, editor_win2);
    set_menu_format(editor_menu, 6, 1);
    set_menu_mark(editor_menu, " * ");
    set_menu_spacing(editor_menu, 1, 1, 1);
    set_menu_grey(editor_menu, 1);
    // 创建并设置菜单

    post_menu(editor_menu);
    wrefresh(editor_win);
    int c;
    while ((c = getch()) != 10)
    {
        switch (c)
        {
        case KEY_UP:
            menu_driver(editor_menu, REQ_UP_ITEM);
            break;
        case KEY_DOWN:
            menu_driver(editor_menu, REQ_DOWN_ITEM);
            break;
        default:
            break;
        }
        wrefresh(editor_win);
    }
    int choice = item_index(current_item(editor_menu));
    unpost_menu(editor_menu);
    free_menu(editor_menu); // 删除菜单
    for (auto it = items.begin(); it != items.end(); ++it)
    {
        free_item(*it);
    }
    // 删除菜单项
    delwin(editor_win);
    delwin(editor_win2);
    // 删除窗口
    clear();
    refresh();
    return editor_list[choice];
    // 返回编辑器名称
}



// 辅助函数：检查路径是否存在
bool path_exists(const std::string &path)
{
    struct stat info;
    return stat(path.c_str(), &info) == 0;
}

// 辅助函数：检查是否是目录
bool is_directory(const std::string &path)
{
    struct stat info;
    if (stat(path.c_str(), &info) != 0)
        return false;
    return S_ISDIR(info.st_mode);
}

// 辅助函数：检查目录是否为空
bool is_directory_empty(const std::string &path)
{
    DIR *dir = opendir(path.c_str());
    if (!dir)
        return false;

    struct dirent *entry;
    int count = 0;
    while ((entry = readdir(dir)) != nullptr)
    {
        if (++count > 2)
            break; // . and .. count as entries
    }
    closedir(dir);
    return count <= 2;
}

// 辅助函数：路径拼接
std::string path_join(const std::string &dir, const std::string &file)
{
    if (dir.empty())
        return file;
    if (dir.back() == '/')
        return dir + file;
    return dir + "/" + file;
}


// 创建单个目录（如果不存在）
bool create_directory(const std::string &path)
{
    if (mkdir(path.c_str(), 0755) == 0)
    {
        return true;
    }
    else
    {
        std::cerr << "Failed to create " << path << " (already exists?)" << std::endl;
        return false;
    }
}

// 创建文件
bool create_file(const std::string &file_path, const std::string &content = "")
{
    std::ofstream file(file_path);
    if (!file.is_open())
        return false;
    file << content;
    file.close();
    return true;
}

int user_init()
{
    // 创建一个空的JSON对象，用来存储学生信息
    nlohmann::json student;

    // 调用major_choice()函数获取学生专业选择，并将结果存储在major字符串中
    std::string major = major_choice();
    // 将专业信息添加到student JSON对象中，使用"major"作为键名
    student["major"] = major;

    // 调用student_info函数，传入student对象，用于添加其他学生信息
    student_info(student);

    // 调用editor_choice()函数获取学生偏好的代码编辑器，并将结果存储在editor字符串中
    std::string editor = editor_choice();
    // 将编辑器偏好添加到student JSON对象中，使用"editor"作为键名
    student["editor"] = editor;

    // 创建一个输出文件流对象outFile，用于写入到student.json文件
    std::ofstream outFile("student.json");
    // 将student JSON对象格式化为带4个空格缩进的字符串，并写入到文件中
    outFile << student.dump(4);
    // 关闭文件流，确保所有数据都已写入文件
    outFile.close();

    const std::vector<std::string> lab = {
        "lab1",
        "lab2",
        "lab3",
        "lab4"
    };

    //构建基础的实验目录
    for (const auto&dir :lab){
        create_directory(dir);
        std::string shell_file = dir+"/"+dir+".sh";
        if(!create_file(shell_file,"")){
            std::cerr << "Failed to create " << shell_file << std::endl;
        }
        std::string demand_file = dir+"/"+dir+".txt";
        if (!create_file(demand_file, ""))
        {
            std::cerr << "Failed to create " << demand_file << std::endl;
        }
    }

    std::string name = student["name"];
    std::string email = student["email"];
    std::string url = student["git"];

    if(!git_init(name,email)){
        return 1;
    }
    if(!git_add()){
        return 1;
    }
    if(!git_commit("init")){
        return 1;
    }
    if(!git_remote_add(url)){
        return 1;
    }
    if(!git_push()){
        return 1;
    }

    return 0;
}